/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package system;

import iddss.Parameters;
import java.math.BigInteger;
import java.security.SecureRandom;

public class RSA {

    private final static BigInteger one = new BigInteger("1");

    private static String[] keys;
    private static long LastGeneration=0;

    /**
     * Generate an 1040-bit (roughly) public and private key
     * @return String[] String[0] - public key; String[1] - private key; String[2] - modulus
     */
    public String[] GenerateKeys() {
        long currentgeneration=Long.parseLong(new getTimeDate().getTimeDate("yyyyMMddHHmmss")); //get current system time
        if((currentgeneration-LastGeneration)>Parameters.KeyGenerationPeriod){ //if need to generate new keys;
        SecureRandom random = new SecureRandom();
        BigInteger privateKey; //private key
        BigInteger publicKey; //public key
        BigInteger modulus; //modulus
        //generating 2 big prime numbers
        BigInteger p = BigInteger.probablePrime(520, random);
        BigInteger q = BigInteger.probablePrime(520, random);
        //phi function (indicator of integer)
        BigInteger phi = (p.subtract(one)).multiply(q.subtract(one));
        //get modulus value
        modulus = p.multiply(q);
        publicKey = new BigInteger("65537");     // common value in practice = 2^16 + 1
        privateKey = publicKey.modInverse(phi);
        String[] ret = {publicKey.toString(), privateKey.toString(), modulus.toString()};
        keys=ret;
        LastGeneration=currentgeneration;
        return ret;
    } else return keys;
    }
    /**
     * Enrypt message
     * @param message String to encrypt (String must have only numbers)
     * @param publicKey - public key
     * @param modulus - the modulus of public key
     * @return String of encrypted text
     */
    public byte[] encrypt(byte[] message, String publicKey, String modulus) {
        BigInteger mes = new BigInteger(message);
        BigInteger Key = new BigInteger(publicKey); //public key
        BigInteger mod = new BigInteger(modulus); //modulus
        return mes.modPow(Key, mod).toByteArray();
    }

    /**
     * Decrypt message
     * @param message String to decrypt (String must have only numbers)
     * @param privateKey - private key
     * @param modulus - the modulus of public key
     * @return String of decrypted text
     */
    public byte[] decrypt(byte[] message, String privateKey, String modulus) {
        BigInteger mes = new BigInteger(message);
        BigInteger Key = new BigInteger(privateKey); //private key
        BigInteger mod = new BigInteger(modulus); //modulus
        return mes.modPow(Key, mod).toByteArray();
    }
}
